package com.hong.qrpc;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * 表示一个服务，字段所描述的就是这个服务方法的特征，用于选择对应的方法进行调用
 *
 * @Author HQT
 * @Data 2022/7/10 7:29
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ServiceDescriptor implements Serializable {
    /**
     * 方法名
     */
    private String method;
    /**
     * 类名
     */
    private String clazz;
    /**
     * 返回值类型
     */
    private String returnType;
    /**
     * 参数类型
     */
    private String[] parameterTypes;

    /**
     * 通过一个接口class和方法创建一个ServiceDescriptor对象
     *
     * @param interfaceClass 接口类
     * @param method         方法对象
     * @return 创建的ServiceDescriptor对象
     */
    public static ServiceDescriptor from(Class interfaceClass, Method method) {
        Class<?>[] parameterTypeClass = method.getParameterTypes();
        String[] parameterTypes = new String[parameterTypeClass.length];
        for (int i = 0; i < parameterTypeClass.length; i++) {
            parameterTypes[i] = parameterTypeClass[i].getName();
        }
        return new ServiceDescriptor(method.getName(), interfaceClass.getName(),
                method.getReturnType().getName(), parameterTypes);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        ServiceDescriptor that = (ServiceDescriptor) o;

        if (getMethod() != null ? !getMethod().equals(that.getMethod()) : that.getMethod() != null) return false;
        if (getClazz() != null ? !getClazz().equals(that.getClazz()) : that.getClazz() != null) return false;
        if (getReturnType() != null ? !getReturnType().equals(that.getReturnType()) : that.getReturnType() != null)
            return false;
        // Probably incorrect - comparing Object[] arrays with Arrays.equals
        return Arrays.equals(getParameterTypes(), that.getParameterTypes());
    }

    @Override
    public int hashCode() {
        int result = getMethod() != null ? getMethod().hashCode() : 0;
        result = 31 * result + (getClazz() != null ? getClazz().hashCode() : 0);
        result = 31 * result + (getReturnType() != null ? getReturnType().hashCode() : 0);
        result = 31 * result + Arrays.hashCode(getParameterTypes());
        return result;
    }

    @Override
    public String toString() {
        return "ServiceDescriptor{" +
                "method='" + method + '\'' +
                ", clazz='" + clazz + '\'' +
                ", returnType='" + returnType + '\'' +
                ", parameterTypes=" + Arrays.toString(parameterTypes) +
                '}';
    }
}
